<template>
  <el-dialog
    v-model="show"
    title="编辑表模型"
    width="840"
    destroy-on-close
    align-center
    draggable
    :before-close="handleDialogClose"
  >
    <el-form
      ref="tableFormRef"
      label-width="auto"
      label-position="right"
      :model="data"
      :rules="rules"
      @keyup.enter="keyUp"
    >
      <el-row :gutter="20" align="bottom">
        <el-col :span="12">
          <el-space fill>
            <el-alert type="info" show-icon :closable="false">
              <p>
                填数据表名，如：tbl_user_info，不能有中文；建议用 'tbl_'
                开头，长度控制在25个字符
              </p>
            </el-alert>
            <el-form-item label="数据表名" prop="name">
              <el-input
                v-model="data.name"
                maxlength="25"
                placeholder="tbl_user_info"
                show-word-limit
                type="text"
              />
            </el-form-item>
          </el-space>
        </el-col>
        <el-col :span="12">
          <el-space fill>
            <el-alert type="info" show-icon :closable="false">
              <p>
                填数据业务表名，如：用户信息表；建议用 '信息表'、'配置表'
                等功能表结尾，长度控制在25个字符
              </p>
            </el-alert>
            <el-form-item label="业务表名" prop="label">
              <el-input
                v-model="data.label"
                maxlength="25"
                placeholder="用户信息表"
                show-word-limit
                type="text"
              />
            </el-form-item>
          </el-space>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="24">
          <el-space fill>
            <el-alert type="info" show-icon :closable="false">
              <p>
                填数据业务表的备注信息。建议是写些，避免后来者不理解表的用途。长度控制在500个字符
              </p>
            </el-alert>
            <el-form-item label="表备注信息" prop="memo">
              <el-input
                v-model="data.memo"
                maxlength="500"
                placeholder="请填写备注信息"
                show-word-limit
                type="textarea"
              />
            </el-form-item>
          </el-space>
        </el-col>
      </el-row>
      <el-table
        :data="data.items"
        show-overflow-tooltip
        stripe
        style="width: 100%"
        max-height="520"
        table-layout="auto"
      >
        <el-table-column type="index" :index="indexMethod" />
        <el-table-column prop="name" label="字段名">
          <template #default="scope">
            <el-tag
              v-for="(c, i) in scope.row.cs"
              :key="i"
              :item="c"
              size="small"
              effect="dark"
              round
              :type="c === 1 ? 'success' : 'primary'"
            >
              <span v-if="c === 1">单</span><span v-else>多</span>
            </el-tag>
            <el-text class="mx-1" type="info"> {{ scope.row.name }} </el-text>
          </template>
        </el-table-column>
        <el-table-column prop="type" label="数据类型">
          <template #default="scope">
            <el-tag>{{ scope.row.type }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="memo" label="备注">
          <template #header> </template>
        </el-table-column>
        <el-table-column fixed="right" label="操作" width="120">
          <template #header> </template>
          <template #default="scope">
            <el-button
              type="primary"
              :icon="Edit"
              circle
              @click="editRow(scope.$index)"
            />
            <el-popconfirm
              title="确定删除表字段么？"
              confirm-button-text="确认"
              cancel-button-text="取消"
              @confirm="deleteRow(scope.$index)"
              @cancel="ElMessage.info('取消删除')"
            >
              <template #reference>
                <el-button type="danger" :icon="Delete" circle />
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
      <el-collapse-transition>
        <div style="height: 50px">
          <el-alert
            v-show="itemsCheckRes"
            type="error"
            :description="itemsCheckRes"
            show-icon
            @close="alertClose"
          />
        </div>
      </el-collapse-transition>
      <el-row justify="space-around">
        <el-col :span="9"></el-col>
        <el-col :span="1">
          <el-button type="warning" :icon="Plus" circle @click="onAddItem" />
        </el-col>
        <el-col :span="9"></el-col>
      </el-row>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-row justify="space-between">
          <el-col :span="2">
            <el-button v-if="showDelete" type="danger" @click="commitDelete">
              删除
            </el-button>
          </el-col>
          <el-col :span="16"
            ><el-button @click="cancel">取消</el-button>
            <el-button type="primary" @click="commit(tableFormRef)"
              >确认</el-button
            >
          </el-col>
        </el-row>
      </div>
    </template>
    <elm-er-table-item-dialog
      v-model:show="itemEditDialog"
      v-model:info="itemInfo"
      :items="data.items"
      @commit="commitAddItem"
    />
  </el-dialog>
</template>

<script lang="ts" setup>
import { ref, reactive, toRef, watch, PropType } from "vue";
import { Plus, Edit, Delete } from "@element-plus/icons-vue";
import { ElMessageBox, ElMessage } from "element-plus";
import { ErTable, ErCol } from "@/components/x6antv";
import type { FormInstance, FormRules } from "element-plus";

const props = defineProps({
    show: {
      type: Boolean,
      default: false,
    },
    data: {
      type: Object as PropType<ErTable>,
      default: () => ({}),
    },
    tables: {
      type: Array as PropType<ErTable[]>,
      default: () => [],
    },
    showDelete: {
      type: Boolean,
      defalue: false,
    },
  }),
  emit = defineEmits([
    "update:show",
    "update:data",
    "delete",
    "cancel",
    "commit",
  ]),
  tableFormRef = ref<FormInstance>(),
  show = toRef(props.show),
  data = toRef(props.data),
  showDelete = toRef(props.showDelete),
  itemEditDialog = ref(false),
  itemInfo = ref<ErCol>(),
  itemIndex = ref(),
  itemsCheckRes = ref(""),
  validateName = (rule: any, value: any, callback: any) => {
    if (value != "") {
      if (props.tables)
        for (let i = 0; i < props.tables.length; i++) {
          const e = props.tables[i];
          if (data.value.id && e.id === data.value.id) continue;
          if (e.name == value) {
            callback(new Error("数据表名已存在"));
            return;
          }
        }
      callback();
    }
  },
  validateLabel = (rule: any, value: any, callback: any) => {
    if (value != "") {
      if (props.tables)
        for (let i = 0; i < props.tables.length; i++) {
          const e = props.tables[i];
          if (data.value.id && e.id === data.value.id) continue;
          if (e.label == value) {
            callback(new Error("业务表名已存在"));
            return;
          }
        }
      callback();
    }
  },
  rules = reactive<FormRules<ErTable>>({
    name: [
      {
        required: true,
        message: "数据表名不能为空",
        trigger: "blur",
      },
      {
        min: 3,
        max: 25,
        message: "字段长度控制在3到25个字符",
        trigger: "blur",
      },
      { validator: validateName, trigger: "blur" },
    ],
    label: [
      {
        required: true,
        message: "业务表名不能为空",
        trigger: "blur",
      },
      {
        min: 2,
        max: 25,
        message: "字段长度控制在3到25个字符",
        trigger: "blur",
      },
      { validator: validateLabel, trigger: "blur" },
    ],
    memo: [
      {
        required: true,
        message: "表的备注信息建议不要空着",
        trigger: "blur",
      },
      {
        max: 500,
        message: "内容长度控制在500个字符内",
        trigger: "blur",
      },
    ],
  }),
  keyUp = (e: any) => {
    if (e.ctrlKey && e.keyCode == 13) {
      commit(tableFormRef.value);
    }
  },
  alertClose = () => {
    itemsCheckRes.value = "";
  },
  indexMethod = (index: number) => {
    return index + 1;
  },
  editRow = (index: number) => {
    itemInfo.value = data.value.items[index];
    if (itemInfo.value) {
      itemIndex.value = index;
      itemEditDialog.value = true;
    }
  },
  deleteRow = (index: number) => {
    data.value.items?.splice(index, 1);
  },
  onAddItem = () => {
    console.log(itemEditDialog.value);
    itemInfo.value = ref<ErCol>({
      id: "",
      name: "",
      type: "String",
      memo: "",
      isIndex: false,
      index: "",
      unique: "",
      cs: [],
    }).value;
    itemIndex.value = -1;
    itemEditDialog.value = true;
  },
  commitDelete = () => {
    ElMessageBox.confirm("你确定删除数据表么?")
      .then(() => {
        emit("delete");
        cancel();
      })
      .catch(() => {
        // catch error
      });
  },
  commitAddItem = (_item: ErCol) => {
    let xitem = {};
    Object.assign(xitem, JSON.parse(JSON.stringify(_item)));
    const item: ErCol = xitem as ErCol;
    if (item.name) {
      if (!item.id) {
        let maxIndex = 0;
        if (data.value.items)
          data.value.items.forEach((e) => {
            const ni = Number(e.id);
            console.log(ni);
            if (maxIndex < ni) maxIndex = ni;
          });
        item.id = maxIndex + 1 + "";
      }
      if (itemIndex.value > -1) {
        data.value.items?.splice(itemIndex.value, 1, item);
      } else {
        if (data.value.items) {
          data.value.items.push(item);
        } else {
          data.value.items = [item];
        }
        console.log(data.value.items);
      }
      itemsCheckRes.value = "";
    }
  },
  cancel = () => {
    show.value = false;
    emit("update:show", show.value);
    emit("cancel");
  },
  commit = async (formEl: FormInstance | undefined) => {
    if (!formEl) return;
    await formEl.validate((valid, fields) => {
      if (valid) {
        if (!data.value.items || data.value.items.length === 0) {
          itemsCheckRes.value = ":)你是不是忘记填表字段了";
          return;
        }
        show.value = false;
        emit("update:show", show.value);
        emit("update:data", data.value);
        emit("commit");
      }
    });
  },
  handleDialogClose = () => {
    ElMessageBox.confirm("你确定关闭对话框么?")
      .then(() => {
        cancel();
      })
      .catch(() => {
        // catch error
      });
  };

watch(
  () => props.show,
  (newValue) => {
    show.value = newValue;
    if (newValue === true) {
      data.value = toRef(props.data).value;
      showDelete.value = toRef(props.showDelete).value;
    }
  }
);
</script>
